#include "cfactory.hpp"
struct sockaddr_in ser;
Zhuce login_msg;
char path[200] = {"/"};
void print(void)
{
    //    system("clear");
    //    printf("Hello %s\n",login_msg.name);
    printf("[%s@Netdisk ~%s]$ ", login_msg.name, path);
    fflush(stdout);
}
int main(int argc, char *argv[])
{
    ARGS_CHECK(argc, 3);
    bzero(&ser, sizeof(ser));
    ser.sin_family = AF_INET;
    ser.sin_port = htons(atoi(argv[2]));
    ser.sin_addr.s_addr = inet_addr(argv[1]);
    int epfd, type, cfd, ret;
    char buf[100], *passwd, *p;
    time_t now;
    Train_t train;
    QUR_msg qq_msg;
    struct epoll_event evs[10];
    epfd = epoll_create(1);
    epoll_func(epfd, 0, EPOLL_CTL_ADD, EPOLLIN);
login_begin:
    system("clear");
    printf("请选择注册或者登陆：\n1:注册新账号\n2:已有账号直接登陆\n");
    scanf("%d", &type);
    if (type == 1)
    {
        printf("请输入要注册的用户名\n");
        scanf("%s", login_msg.name);
        passwd = getpass("请输入密码：");
        strcpy(buf, passwd);
        passwd = getpass("请再次输入密码确认：");
        if (strcmp(buf, passwd) != 0)
        {
            printf("两次输入不一致，即将回到主界面\n");
            sleep(1);
            goto login_begin;
        }
        else
        {
            strcpy(train.buf, login_msg.name);
            train.len = strlen(train.buf) + 1;
            train.ctl_code = LOGIN_PRE;
            cfd = socket(AF_INET, SOCK_STREAM, 0);
            ERROR_CHECK(cfd, -1, "socket");
            ret = connect(cfd, (struct sockaddr *)&ser, sizeof(ser));
            ERROR_CHECK(ret, -1, "connect");
            ret = send(cfd, &train, train.len + 8, 0);
        }
    }
    else
    {
        printf("请输入要登录的用户名\n");
        scanf("%s", login_msg.name);
        passwd = getpass("请输入密码：");
        strcpy(buf, passwd);
        strcpy(train.buf, login_msg.name);
        train.len = strlen(train.buf) + 1;
        train.ctl_code = REGISTER_PRE;
        cfd = socket(AF_INET, SOCK_STREAM, 0);
        ERROR_CHECK(cfd, -1, "socket");
        ret = connect(cfd, (struct sockaddr *)&ser, sizeof(ser));
        ERROR_CHECK(ret, -1, "connect");
        ret = send(cfd, &train, train.len + 8, 0);
    }
    epoll_func(epfd, cfd, EPOLL_CTL_ADD, EPOLLIN);
    while (1)
    {
        int ready_num = epoll_wait(epfd, evs, 10, -1);
        for (int i = 0; i < ready_num; i++)
        {
            if (evs[i].events == EPOLLIN && evs[i].data.fd == cfd)
            {
                ret = one_recv(cfd, &train);
                if (ret == -1)
                {
                    epoll_func(epfd, cfd, EPOLL_CTL_DEL, EPOLLIN);
                    close(cfd);
                    cfd = socket(AF_INET, SOCK_STREAM, 0);
                    ERROR_CHECK(cfd, -1, "socket");
                    ret = connect(cfd, (struct sockaddr *)&ser, sizeof(ser));
                    ERROR_CHECK(ret, -1, "connect");
                    epoll_func(epfd, cfd, EPOLL_CTL_ADD, EPOLLIN);
                    train.len = sizeof(Zhuce);
                    memcpy(train.buf, &login_msg, train.len);
                    train.ctl_code = TOKEN_PLESE;
                    ret = send(cfd, &train, train.len + 8, 0);
                    if (ret == -1)
                    {
                        exit(0);
                    }
                    continue;
                }
                switch (train.ctl_code)
                {
                case LOGIN_NO:
                    epoll_func(epfd, cfd, EPOLL_CTL_DEL, EPOLLIN);
                    close(cfd);
                    printf("账号已存在，请重新注册\n");
                    sleep(1);
                    goto login_begin;
                case LOGIN_POK:
                    strcpy(login_msg.token, train.buf); // 这时token里面的是盐值
                    strcpy(login_msg.passward, crypt(buf, login_msg.token));
                    train.len = sizeof(Zhuce);
                    memcpy(train.buf, &login_msg, train.len);
                    train.ctl_code = LOGIN_Q;
                    ret = send(cfd, &train, train.len + 8, 0);
                    if (ret != -1)
                        printf("注册成功\n");
                    else
                        printf("网络繁忙，注册失败\n");
                    sleep(1);
                    epoll_func(epfd, cfd, EPOLL_CTL_DEL, EPOLLIN);
                    close(cfd);
                    goto login_begin;
                case REGISTER_NO:
                    printf("账号/密码错误，请重新登录\n");
                    epoll_func(epfd, cfd, EPOLL_CTL_DEL, EPOLLIN);
                    close(cfd);
                    sleep(1);
                    goto login_begin;
                case REGISTER_POK:
                    time(&now);
                    strcpy(login_msg.passward, crypt(buf, train.buf));
                    sprintf(login_msg.token, "%s %s", login_msg.name, ctime(&now));
                    login_msg.token[strlen(login_msg.token) - 1] = 0;
                    train.len = sizeof(Zhuce);
                    memcpy(train.buf, &login_msg, train.len);
                    train.ctl_code = REGISTER_Q;
                    ret = send(cfd, &train, train.len + 8, 0);
                    break;
                case REGISTER_OK:
                    system("clear");
                    printf("Hello: %s\n", login_msg.name);
                    printf("\n    登录成功\n\n");
                    printf("    'ps'----查看上传/下载进度\n\n    'rm'----删除文件或者文件夹（不能为空）\n");
                    printf("\n    'exit'----退出程序\n\n");
                    printf("    'mgets'----VIP多点下载\n\n");
                    strcpy(login_msg.passward, "0"); // code值为0；
                    getchar();
                    print();
                    break;
                case LS_OK:
                    printf("%s", train.buf);
                    printf("[%s@Netdisk ~%s]$ ", login_msg.name, path);
                    fflush(stdout);
                    break;
                case OPERATE_NO:
                    printf("参数错误，操作失败\n");
                    print();
                    break;
                case OPERATE_OK:
                    if (train.len > 0)
                    {
                        memcpy(&qq_msg, train.buf, train.len);
                        //  strcpy(code,qq_msg.buf);
                        strcpy(login_msg.passward, qq_msg.buf);
                        strcpy(path, qq_msg.buf1);
                    }
                    print();
                    break;
                case DOWNLOAD_POK:
                    break;
                case UPLOAD_OK:
                    break;
                case UPLOAD_POK:
                    break;
                case DOWN_MORE_POK:
                    break;
                }
            }
            if (evs[i].events == EPOLLIN && evs[i].data.fd == 0)
            {
                fgets(buf, 100, stdin);
                buf[strlen(buf) - 1] = 0;
                p = buf;
                while (*p != ' ' && *p != 0)
                    p++;
                if (*p != 0)
                    *(p++) = 0;
                if (strcmp(buf, "ls") == 0)
                {
                    train.len = 0;
                    train.ctl_code = LS_Q;
                    ssend(&cfd, epfd, &train);
                }
                else if (strcmp(buf, "cd") == 0 || strcmp(buf, "mkdir") == 0 || strcmp(buf, "rm") == 0)
                {
                    strcpy(qq_msg.buf, buf);
                    strcpy(qq_msg.buf1, p);
                    train.len = sizeof(QUR_msg);
                    train.ctl_code = OPERATE_Q;
                    memcpy(train.buf, &qq_msg, train.len);
                    ssend(&cfd, epfd, &train);
                }
            }
        }
    }
    return 0;
}